home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / db / esm-3.1 / esm-3 / usr / local / sm / src / serverlib / lm / initializeLocks.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-05  |  8.0 KB  |  287 lines

  1. /*
  2.  *   $RCSfile: initializeLocks.c,v $  
  3.  *   $Revision: 1.1.1.1 $  
  4.  *   $Date: 1996/05/04 21:55:51 $      
  5.  */ 
  6. /**********************************************************************
  7. * EXODUS Database Toolkit Software
  8. * Copyright (c) 1991 Computer Sciences Department, University of
  9. *                    Wisconsin -- Madison
  10. * All Rights Reserved.
  11. *
  12. * Permission to use, copy, modify and distribute this software and its
  13. * documentation is hereby granted, provided that both the copyright
  14. * notice and this permission notice appear in all copies of the
  15. * software, derivative works or modified versions, and any portions
  16. * thereof, and that both notices appear in supporting documentation.
  17. *
  18. * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
  19. * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.  
  20. * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  21. * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  22. *
  23. * The EXODUS Project Group requests users of this software to return 
  24. * any improvements or extensions that they make to:
  25. *
  26. *   EXODUS Project Group 
  27. *     c/o David J. DeWitt and Michael J. Carey
  28. *   Computer Sciences Department
  29. *   University of Wisconsin -- Madison
  30. *   Madison, WI 53706
  31. *
  32. *     or exodus@cs.wisc.edu
  33. *
  34. * In addition, the EXODUS Project Group requests that users grant the 
  35. * Computer Sciences Department rights to redistribute these changes.
  36. **********************************************************************/
  37.  
  38. #include "sysdefs.h"
  39. #include "ess.h"
  40. #include "checking.h"
  41. #include "trace.h"
  42. #include "error.h"
  43. #include "list.h"
  44. #include "pool.h"
  45. #include "tid.h"
  46. #include "io.h"
  47. #include "lock.h"
  48. #include "object.h"
  49. #include "msgdefs.h"
  50. #include "thread.h"
  51. #include "semaphore.h"
  52. #include "link.h"
  53. #include "lsn.h"
  54. #include "latch.h"
  55. #include "bf.h"
  56. #include "volume.h"
  57. #include "trans.h"
  58. #include "util_funcs.h"
  59. #include "lm_intfuncs.h"
  60. #include "lm_extfuncs.h"
  61. #include "lm_globals.h"
  62. #include "lock_globals.h"
  63. #include "thread_globals.h"
  64.  
  65. static void
  66. initLockEntry(LOCKENTRY *lockEntry) 
  67. {
  68.     TRACE(TR_LOCK, TR_LEVEL_1);
  69.     initializeListElement( &(lockEntry->transList), (char *) lockEntry );
  70.     initializeListElement( &(lockEntry->ageList), (char *) lockEntry );
  71.     initializeListElement( &(lockEntry->headerList.list), (char *) lockEntry );
  72.     initializeList( &(lockEntry->threadList) );
  73.     INIT_LOCKENTRY_MAGIC(lockEntry);
  74.     /* the rest of the fields are initialized in newLockEntry(), because they
  75.      * need to be REinitialized for re-use after they are put back in the Pool. 
  76.      */
  77. }
  78.  
  79.  LOCKENTRY
  80. *allocLockEntry (
  81.     POOL        *head 
  82. )
  83. {
  84.     LOCKENTRY    *lockEntry;
  85.  
  86.     TRACE(TR_LOCK, TR_LEVEL_1);
  87.     if ((lockEntry = (LOCKENTRY *) malloc(sizeof(LOCKENTRY))) == NULL)    {
  88.         SM_ERROR(TYPE_FATAL, esmMALLOCFAILED);
  89.     }
  90.     initLockEntry(lockEntry);
  91.     head->elements++;
  92.     return(lockEntry);
  93. }
  94.  
  95.  void
  96. initializeLocks ()
  97. {
  98.     LIST            *lockList;
  99.     LOCKHEADER        *lockHeader;
  100.     LOCKENTRY        *lockEntry;
  101.     LOCKCLASSREC    *lockClass;
  102.     UFOUR            spaceNeeded;
  103.     FOUR            i;
  104.  
  105.  
  106.     TRACE(TR_LOCK, TR_LEVEL_1);
  107.  
  108.     /*
  109.      * LOCK TABLE 
  110.      */
  111.  
  112.     if (!checkLog2(LockTableSize))    {
  113.         /* LockTableSize must be a power of two */
  114.         SM_ERROR(TYPE_FATAL, esmBADLOCKTABLESIZE);
  115.     } else {
  116.         LockHashMask = LockTableSize - 1;
  117.     }
  118.     TRPRINT(TR_LOCK, TR_LEVEL_2, ("LockTableSize:%d LockHashMask:%x",
  119.             LockTableSize, LockHashMask));
  120.     spaceNeeded = sizeof(LIST) * LockTableSize;
  121.     if ((lockList = (LIST *) malloc(spaceNeeded)) == NULL)    {
  122.         SM_ERROR(TYPE_FATAL, esmMALLOCFAILED);
  123.     }
  124.     LockHashTable = lockList;
  125.     for (i = 0; i < LockTableSize; i++, lockList++)    {
  126.         initializeList(lockList);
  127.     }
  128.  
  129.     /*
  130.      * LOCK HEADER POOL
  131.      */
  132.     initializePool( &LockHeaderPool, (ALLOCFUNC) allocLockHeader, NumLockHeaders );
  133.     spaceNeeded = sizeof(LOCKHEADER) * NumLockHeaders;
  134.     if ((lockHeader = (LOCKHEADER *) malloc(spaceNeeded)) == NULL)    {
  135.         SM_ERROR(TYPE_FATAL, esmMALLOCFAILED);
  136.     }
  137.     for (i = 0; i < NumLockHeaders; i++, lockHeader++)    {
  138.         initializeListElement( &(lockHeader->hashList.list), (char *) lockHeader );
  139.         listEnq( &(LockHeaderPool.freeList), &(lockHeader->hashList.list) );
  140.         initializeList( &(lockHeader->grantedList) );
  141.         initializeList( &(lockHeader->waitList) );
  142.         initializeList( &(lockHeader->upgradeList) );
  143.         initializeList( &(lockHeader->auxList) );
  144.         INIT_LOCKHEADER_MAGIC(lockHeader);
  145.     }
  146.  
  147.     /*
  148.      *    LOCK ENTRY POOL
  149.      */
  150.     initializePool( &LockEntryPool, (ALLOCFUNC) allocLockEntry, NumLockEntries );
  151.     spaceNeeded = sizeof(LOCKENTRY) * NumLockEntries;
  152.     if ((lockEntry = (LOCKENTRY *) malloc(spaceNeeded)) == NULL)    {
  153.         SM_ERROR(TYPE_FATAL, esmMALLOCFAILED);
  154.     }
  155.     for (i = 0; i < NumLockEntries; i++, lockEntry++)    {
  156.         initLockEntry(lockEntry);
  157.         listEnq( &(LockEntryPool.freeList), &(lockEntry->transList) );
  158.     }
  159.  
  160.     /*
  161.      *    LOCK CLASS POOL
  162.      */
  163.     initializePool( &LockClassPool, (ALLOCFUNC) allocLockClassRec, NumLockClassRecs );
  164.     spaceNeeded = sizeof(LOCKCLASSREC) * NumLockClassRecs;
  165.     if ((lockClass = (LOCKCLASSREC *) malloc(spaceNeeded)) == NULL)    {
  166.         SM_ERROR(TYPE_FATAL, esmMALLOCFAILED);
  167.     }
  168.     for (i = 0; i < NumLockClassRecs; i++, lockClass++)    {
  169.         initializeListElement( &(lockClass->transList), (char *) lockClass );
  170.         initializeListElement( &(lockClass->entryList.list), (char *) lockClass );
  171.         listEnq( &(LockClassPool.freeList), &(lockClass->entryList.list) );
  172.         INIT_LOCKCLASSREC_MAGIC(lockClass);
  173.     }
  174. }
  175.  
  176.  LOCKENTRY
  177. *newLockEntry (
  178.     register TRANSREC        *transRec,
  179.     LOCKHEADER                *lockHeader,
  180.     int                        whichList,
  181.     LOCKMODE                 requestMode
  182. )
  183. {
  184.  
  185.     register LOCKENTRY        *lockEntry;
  186.  
  187.  
  188.     TRACE(TR_LOCK, TR_LEVEL_1);
  189.  
  190.     /*
  191.      *    attempt to get a lock entry structure
  192.      */
  193.     if ((lockEntry = (LOCKENTRY *) poolDeq( &LockEntryPool )) == NULL)    {
  194.         SM_ERROR(TYPE_FATAL, esmNOFREELOCKENTRY);
  195.         return(NULL);
  196.     }
  197.  
  198.     lockEntry->lockHeader = lockHeader;
  199.     lockEntry->headerList.transRec = transRec;
  200.  
  201.     switch (whichList)    {
  202.  
  203.         case GRANT_LIST:
  204.  
  205.             listPush( &(lockHeader->grantedList), &(lockEntry->headerList.list) );
  206.             listPush( &(transRec->lockGrantedList), &(lockEntry->transList) );
  207.             lockEntry->flags = LOCK_GRANTED;
  208.             break;
  209.  
  210.         case WAIT_LIST:
  211.  
  212.             listEnq( &(lockHeader->waitList), &(lockEntry->headerList.list) );
  213.             listPush( &(transRec->lockWaitList), &(lockEntry->transList) );
  214.             lockEntry->flags = LOCK_WAITER;
  215.             break;
  216.  
  217.         case UPGRADE_LIST:
  218.  
  219.             listEnq( &(lockHeader->upgradeList), &(lockEntry->headerList.list) );
  220.             listPush( &(transRec->lockUpgradeList), &(lockEntry->transList) );
  221.             lockEntry->flags = LOCK_UPGRADE;
  222.             break;
  223.  
  224.         default:
  225.             
  226.             SM_ERROR(TYPE_FATAL, esmINTERNAL);
  227.             break;
  228.     }
  229.  
  230.     lockEntry->lockMode = requestMode;
  231.     lockEntry->time2wakeup = 0;
  232.     lockEntry->weight = 0;
  233.  
  234.     /*
  235.      *    return a pointer to the lock entry
  236.      */
  237.     TRPRINT(TR_LOCK, TR_LEVEL_1,
  238.         ("Thread %d, trans %ld, ALLOCating 0x%x mode=%s flag=%d",
  239.         Active->id, Active->message.header.params.in.tid, lockEntry,
  240.         GETMODE(lockEntry->lockMode), (int)lockEntry->flags));
  241.     TRPRINT(TR_LOCK, TR_LEVEL_1,
  242.         ("lock (id %s) entry for trans %d",
  243.             printLockId(lockEntry->lockHeader->hashList.lockid),
  244.         lockEntry->headerList.transRec->tid) );
  245.  
  246.     return(lockEntry);
  247. }
  248.  void
  249. freeLockEntry (
  250.     register LOCKENTRY    *lockEntry,
  251.     int                    error 
  252. )
  253. {
  254.     TRACE(TR_LOCK, TR_LEVEL_1);
  255.  
  256.     TRPRINT(TR_LOCK, TR_LEVEL_1,
  257.         ("Thread %d, trans %ld, FREEing 0x%x mode=%s flag=%d",
  258.         Active->id, Active->message.header.params.in.tid, lockEntry,
  259.         GETMODE(lockEntry->lockMode), (int)lockEntry->flags));
  260.     TRPRINT(TR_LOCK, TR_LEVEL_1,
  261.         ("lock (id %s) entry for trans %d",
  262.         lockEntry->flags & LOCK_UPGRADE ?
  263.             printLockId(((LOCKENTRY*)lockEntry->lockHeader)->lockHeader->hashList.lockid) :
  264.             printLockId(lockEntry->lockHeader->hashList.lockid),
  265.         lockEntry->headerList.transRec->tid) );
  266.  
  267.     lockEntry->headerList.transRec->lockWeight -= lockEntry->weight;
  268.  
  269.     /*
  270.      * take it off the list of lockEntries to be aged
  271.      */
  272.     if(LIST_MEMBER (&(lockEntry->ageList)) ) {
  273.         listRemove(&(lockEntry->ageList));
  274.         lockEntry->time2wakeup = 0;
  275.     } else {
  276.         SM_ASSERT(LEVEL_1, (lockEntry->time2wakeup == 0));
  277.     }
  278.     if (LIST_NOT_EMPTY( &(lockEntry->threadList) ))    {
  279.  
  280.         notify( &(lockEntry->threadList), 
  281.             ((error == esmNOERROR)? esmNOERROR: esmFAILURE), error );
  282.     }
  283.  
  284.     listRemove( &(lockEntry->headerList.list) );
  285.     poolMove( &LockEntryPool, &(lockEntry->transList) );
  286. }
  287.